package com.xuecheng.auth.controller;

import com.alibaba.druid.util.StringUtils;
import com.xuecheng.api.auth.AuthControllerApi;
import com.xuecheng.auth.service.AuthService;
import com.xuecheng.framework.domain.ucenter.ext.AuthToken;
import com.xuecheng.framework.domain.ucenter.request.LoginRequest;
import com.xuecheng.framework.domain.ucenter.response.AuthCode;
import com.xuecheng.framework.domain.ucenter.response.JwtResult;
import com.xuecheng.framework.domain.ucenter.response.LoginResult;
import com.xuecheng.framework.exception.ExceptionCast;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.framework.utils.CookieUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author zhaoxiang
 * @version 1.0
 * @Date 2020/2/14 16:11
 */
@RestController
@RequestMapping("/")
public class AuthController implements AuthControllerApi {

    @Autowired
    private AuthService authService;
    @Value("${auth.clientId}")
    private String clientId;
    @Value("${auth.clientSecret}")
    private String clientSecret;
    //域名
    @Value("${auth.cookieDomain}")
    private String cookieDomain;
    //cookie有效期
    @Value("${auth.cookieMaxAge}")
    private int cookieMaxAge;
    @Value("${auth.tokenValiditySeconds}")
    private int tokenValiditySeconds;

    /**
     * 用户登录认证
     *
     * @param loginRequest
     * @return
     */
    @Override
    @PostMapping("/userlogin")
    public LoginResult login(LoginRequest loginRequest) {
        if(loginRequest == null || StringUtils.isEmpty(loginRequest.getUsername())){
            ExceptionCast.cast(AuthCode.AUTH_USERNAME_NONE);
        }
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        AuthToken authToken = authService.login(username, password, clientId, clientSecret);
        //用户身份令牌
        String access_token = authToken.getAccess_token();
        //将令牌存储到cookie
        this.saveCookie(access_token);
        return new LoginResult(CommonCode.SUCCESS, access_token);
    }

    /**
     * 将令牌存储到cookie
     * @param token
     */
    private void saveCookie(String token){
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        //HttpServletResponse response,String domain,String path, String name,
        //                                 String value, int maxAge,boolean httpOnly)
        //flase 浏览器允许获取cookie
        CookieUtil.addCookie(response, cookieDomain, "/", "uid", token, cookieMaxAge, false);
    }

    /**
     * 从cookie中清楚令牌
     * @return
     */
    private void clearCookie(String token){
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        //HttpServletResponse response,String domain,String path, String name,
        //                                 String value, int maxAge,boolean httpOnly)
        //flase 浏览器允许获取cookie
        CookieUtil.addCookie(response, cookieDomain, "/", "uid", token, 0, false);
    }

    /**
     * 用户退出操作
     * @return
     */
    @Override
    @PostMapping("/userlogout")
    public ResponseResult logout() {
        //取出身份令牌
        String tokenFormCookie = getTokenFormCookie();
        //删除redis中的token
        boolean result = authService.delToken(tokenFormCookie);
        //清除cookie
        clearCookie(tokenFormCookie);
        return new ResponseResult(CommonCode.SUCCESS);
    }

    /**
     * 查询userjwt令牌
     * @return
     */
    @Override
    @GetMapping("/userjwt")
    public JwtResult userJwt() {
        //取出cookie中的用户身份令牌（jti）
        String jti = getTokenFormCookie();
        //拿身份令牌从redis中查询jwt(jti)令牌
        AuthToken authToken = authService.getUserToken(jti);
        if (authToken != null){
            //将jwt令牌返回给用户
            return new JwtResult(CommonCode.SUCCESS,authToken.getJwt_token());
        }
        return new JwtResult(CommonCode.FAIL,null);
    }

    /**
     * 从cookie中读取访问令牌
     * @return
     */
    private String getTokenFormCookie(){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        Map<String, String> cookieMap = CookieUtil.readCookie(request, "uid");
        if (cookieMap != null && cookieMap.get("uid") != null){
            String jti = cookieMap.get("uid");
            return jti;
        }
        return null;
    }
}
